package com.pmcc.core.service;

import com.pmcc.core.dto.OrganizationVo;
import com.pmcc.core.entity.security.Employee;
import com.pmcc.core.entity.security.Organization;
import com.pmcc.core.repository.EmployeeRepository;
import com.pmcc.core.repository.OrganizationRepository;
import com.pmcc.core.vo.OrgVo;
import com.pmcc.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by tomas on 2018/4/9.
 */
@Service
@Transactional
public class OrganizationService {
    @Autowired
    EmployeeRepository employeeRepository;
    @Autowired
    OrganizationRepository organizationRepository;


    /**
     * 未使用
     *
     * @return
     */
    public List<OrganizationVo> queryTreeGrid(String parentId) {
        List<Organization> list = new ArrayList<Organization>();
        if ("".equals(parentId) || parentId == null) {
            list = organizationRepository.findByParentIdAndDelFlag("root", 0);
        } else {
            list = organizationRepository.findByParentIdAndDelFlag(parentId, 0);
        }
        List<OrganizationVo> voList = new ArrayList();
        if (list != null && list.size() > 0) {
            OrganizationVo vo = null;
            for (Organization organization : list) {
                vo = new OrganizationVo();
                vo.setId(organization.getId());
                vo.setText(organization.getcName());
                vo.setCode(organization.getCode());
                vo.setLevel(organization.getLevel());
                vo.setParentId(organization.getParentId());
                vo.setEname(organization.geteName());
                vo.setStatus(organization.getStatus());
                vo.setSortNo(organization.getSortNo());
                // 是否有下一级
                List<Organization> childList = organizationRepository.findByParentIdAndDelFlag(organization.getId(), 0);
                if (childList != null && childList.size() > 0) {
                    vo.setState("closed");
                } else {
                    vo.setState("open");
                }
                voList.add(vo);
            }
        }
        return voList;
    }

    public ResultBean queryByPage(AntdPage antdPage, Organization model) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            Page page = organizationRepository.findAll(this.getSpecifition(model), antdPage.getPageRequest());
            resultBean.setPage(antdPage.getDefaultCurrent());
            resultBean.setTotal(page.getTotalElements());
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setPageSize(antdPage.getPageSize());
            resultBean.setRows(page.getContent());
        } catch (Exception e) {
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    public Specification<Organization> getSpecifition(Organization model) {
        return new Specification<Organization>() {
            @Override
            public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
                List<Predicate> list = new ArrayList<>();
                //code
                if(StringUtil.isNotEmpty(model.getCode())){
                    list.add(builder.like(root.get("code").as(String.class),  model.getCode().trim()+"%"));
                }
                list.add(builder.equal(root.get("delFlag").as(Integer.class), 0));
                Predicate[] p = new Predicate[list.size()];
                return builder.and(list.toArray(p));
            }
        };
    }

    /**
     * 新增
     * @param model
     * @return
     */
    public ResultBean addOrganization(Organization model) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            model.setCreateTime(new Date());
            model.setCreateName(OnlineUser.getName());
            //生成自增长编码
            model.setCode(createAddMark(model.getParentId()));
            model.setDelFlag(0);
            organizationRepository.saveAndFlush(model);
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setObject(model);
        } catch (Exception e) {
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 修改
     * @param map
     * @return
     */
    public ResultBean update(Map map) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            Organization c = organizationRepository.findById(map.get("id").toString());
            BeanUtils.setBeanData(c, map);
            organizationRepository.saveAndFlush(c);
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setObject(c);
        } catch (Exception e) {
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    public ResultBean deleteById(String id, Integer flag) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            Organization f = organizationRepository.findById(id);
            f.setDelFlag(flag);
            organizationRepository.saveAndFlush(f);
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setResultDesc("删除成功");
        } catch (Exception e) {
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    public ResultBean queryById(AntdPage antdPage, String id) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        Organization organization = organizationRepository.findById(id);
        if (organization == null) {
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setRows(null);
        } else {
            Employee employee = new Employee();
            employee.setSysOrgId(id);
            Page page = employeeRepository.findAll(this.getSpecifition(employee), antdPage.getPageRequest());
            resultBean.setPage(antdPage.getDefaultCurrent());
            resultBean.setTotal(page.getTotalElements());
            resultBean.setResultCode(ResultBean.SUCCESS);
            resultBean.setPageSize(antdPage.getPageSize());
            resultBean.setRows(page.getContent());
        }
        return resultBean;
    }


    public Specification<Employee> getSpecifition(Employee model) {
        return new Specification<Employee>() {
            @Override
            public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
                List<Predicate> list = new ArrayList<>();

                list.add(builder.equal(root.get("delFlag").as(Integer.class), 0));
                Predicate[] p = new Predicate[list.size()];
                return builder.and(list.toArray(p));
            }
        };
    }

    /**
     * 传入实体，获取list子节点 service
     *
     * @param org
     * @return
     */

    public List<OrgVo> getChildren(Organization org) {//传的参数应该是OrgVo
        List<OrgVo> children = new ArrayList<>();
        List<Organization> childrenOrg = organizationRepository.findByParentIdAndDelFlag(org.getId(), 0);
        if (childrenOrg.size() > 0) {
            for (Organization c : childrenOrg) {
                OrgVo vo = OrgVo.getOrgVo(c);
                children.add(vo);
            }
        }
        return children;
    }

    /**
     * 递归查询所有组织机构
     * 组织机构管理 获取treegrid 使用
     *
     * @param orgVo
     * @return
     */
    public OrgVo traversalOrg(OrgVo orgVo) {
        List<Organization> organizations = organizationRepository.findByParentIdAndDelFlagOrderByCodeAsc(orgVo.getId(), 0);
        List<OrgVo> eleNodeVos = new ArrayList<>();
        if (organizations.size() > 0) {
            for (Organization o : organizations) {
                OrgVo vo = OrgVo.getOrgVo(o);
                OrgVo eleNodeVo2 = this.traversalOrg(vo);
                eleNodeVos.add(eleNodeVo2);
            }
            orgVo.setChildren(eleNodeVos);
        }
        return orgVo;
    }

    /**
     * 查询组织机构树
     *
     * @return
     */
    @Transactional(readOnly = true)
    public List<OrgVo> queryOrg(Organization organization) {
       /* String id = organization.getId();
        List<OrgVo> list = null;
        if ("".equals(id) || id == null) {
            list = this.getParent("root");
        } else {
            list = this.getChildren(organization);
        }
        if (list != null && list.size() > 0) {
            for (OrgVo orgVo : list) {
                List<OrgVo> childrenList = this.getChildren(orgVo);
                if (childrenList.size() > 0) {
                    orgVo.setChildren(new ArrayList<>());
                }
            }
        }*/
        return this.queryList();
    }

    /**
     * 查询所有父级菜单
     *
     * @param parentId
     * @return
     */
    public List<OrgVo> getParent(String parentId) {
        List<OrgVo> parent = new ArrayList<>();
        List<Organization> parentOrg = organizationRepository.findByParentIdAndDelFlag(parentId, 0);
        if (parentOrg.size() > 0) {
            for (Organization c : parentOrg) {
                OrgVo vo = OrgVo.getOrgVo(c);
                parent.add(vo);
            }
        }
        return parent;
    }

    /**
     * 组织机构查询
     *
     * @return
     */
    public List<OrgVo> queryList() {
        List<OrgVo> list = null;
        OrgVo orgVo = null;
        Organization organization = new Organization();
        organization.setId("root");
        OrgVo vo = OrgVo.getOrgVo(organization);
        orgVo = this.traversalOrg(vo);
        return orgVo.getChildren();
    }


    /**
     * 返回新增的可变长 机构增长码
     *
     * @param parentId 所选上级机构id
     * @return
     */

    public String createAddMark(String parentId) {
        String str = "";
        List<Organization> list = new ArrayList<>();
        if ("root".equals(parentId)) {
            list = organizationRepository.findByParentIdAndDelFlag(parentId, 0);
            if (list != null && list.size() > 0) {
                int n = 0;
                for (int m = 1; m <= 20; m++) {
                    String tr = m <= 9 ? m+"0" : m + "";
                    List<Organization> organizationList = organizationRepository.findByParentIdAndCodeAndDelFlag("root", tr, 0);
                    if (organizationList == null || organizationList.size() <= 0) {
                        n = m;
                        break;
                    }
                }
                str = n + "0";
            } else {
                str = 1 + "0";
            }
        } else {
            String parentCode = organizationRepository.getOne(parentId).getCode();
            list = organizationRepository.findByParentIdAndDelFlag(parentId, 0);
            if (list != null && list.size() > 0) {
                if (judgeAndNew(parentCode + createStr(list.size(), parentId))) {
                    int i = 1;
                    while (true) {
                        if (!judgeAndNew(parentCode + createStr(list.size() + i, parentId))) {
                            str = parentCode + createStr(list.size() + i, parentId);
                            break;
                        }
                        i++;
                    }
                } else {
                    str = parentCode + createStr(list.size(), parentId);
                }
            } else {
                str = parentCode + "01";
                /*if ("".equals(organizationDao.get(parentId).getParentId()) || (organizationDao.get(parentId).getParentId()) == null) {
                    str = parentCode + "1";
                } else {
                    str = parentCode + "01";
                }*/
            }
        }
        return str;
    }

    /**
     * 根据对应 整数 生成最少两位字符串
     *
     * @param m
     * @return
     */
    public String createStr(int m, String parentId) {
        String str = "";
        if (m <= 9) {
            if ("root".equals(organizationRepository.getOne(parentId))) {
                str = "0" + m;
            } else {
                str = "0" + m;//新编码
            }
        } else {
            str = "" + m;
        }
        return str;
    }

    /**
     * 判断生成 编码是否 已被使用
     *
     * @param newCode
     * @return
     */
    public boolean judgeAndNew(String newCode) {
        List<Organization> list = organizationRepository.findByCodeAndDelFlag(newCode, 0);
        if (list != null && list.size() > 0) {
            return true;//已被占有
        } else {
            return false;//可以使用
        }
    }


    public List<String> queryByCode(String code) {
        Organization org=new Organization();
        org.setCode(code);
        List<String> str=new ArrayList<>();
       List<Organization> list=organizationRepository.findAll(this.getSpecifition(org));
        for(Organization o:list){
            str.add(o.getId());
        }
        return  str;
    }

    public List<Organization> queryAll(){
        List<Organization> list=new ArrayList<>();
        try{
            list=organizationRepository.findByDelFlag(0);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }
}
